package utils;

import info.clearthought.layout.TableLayout;

import java.awt.Color;
import java.awt.Component;
import java.util.Observable;
import java.util.Observer;
import java.util.Vector;

import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;

import components.RPSList;


/**
 * A GUI component to show the list of tables.
 *
 * @see {@link utils.TableList}
 */
public class TableListGUI extends RPSList implements Observer {

	private static final long serialVersionUID = 1L;
	
	private static final int TABLE_NUM_DOESNT_EXIST = -1;
	private static final String NONE_STRING = "-None-";
	private static final String NAMES_TYPES_SEPARATOR = "     ";
	
	private static final Color COLOR_SELECTED_BACKGROUND = new Color(180, 180, 180);
	private static final Color COLOR_SELECTED_FOREGROUND = Color.BLACK;
	private static final Color COLOR_UNSELECTED_BACKGROUND = Color.WHITE;
	private static final Color COLOR_UNSELECTED_FOREGROUND = Color.BLACK;

	private TableList tableList = null;

	public TableListGUI (TableList tableList) {
		super ();

		this.tableList = tableList;

	    // Add observer on changes to the table list.
		this.tableList.addObserver (this);	
		setCellRenderer(new TableListRenderer ());
		
		setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		
		// Refresh the GUI
	    refresh ();
	}

	/**
	 * Refresh method which updates the visual userlist.
	 */
	public void refresh () {
	    if (tableList != null) {
			int [] tableNums = tableList.getTablesNumbers();
			Vector<Table> listData = new Vector<Table> ();
			for (int i = 0; i < tableNums.length; i++) {
				Table table = tableList.getTable(tableNums[i]);
				listData.add (table);
			}

			//convert to a table at some stage
			setListData (listData);
		}
	}

	/**
	 * Return the selected table number.
	 *
	 * @return  The selected table's number. If nothing is selected, TABLE_NUM_DOESNT_EXIST is returned.
	 */
	public int getSelectedTableNum () {
		int index = getSelectedIndex();		
		int [] tableNums = tableList.getTablesNumbers();
		if (index >= 0 && index < tableNums.length)			
		    return tableNums [index];
		return TABLE_NUM_DOESNT_EXIST;
	}

	public Table getSelectedTable () {		
		if (tableList != null) {
			int tableNum = getSelectedTableNum();
			if (tableNum != TABLE_NUM_DOESNT_EXIST) {
				// Retrieve User object
				return tableList.getTable(tableNum);
			}
		}
		return null;
	}
	
    /**
     * Refresh when the data has been updated on the userlist.
     * 
     * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
     */
    public void update (Observable obs, Object str) {
        refresh ();
    }	
    
    
    /**
     * Custom renderer for the list of tables.
     */
	private class TableListRenderer extends JPanel implements ListCellRenderer {         

		private static final long serialVersionUID = 1L;
		
		private JLabel tableNumLabel;
		private JLabel playersNamesLabel;

        public TableListRenderer () {
        	// Create layout
        	double pref = TableLayout.PREFERRED, fill = TableLayout.FILL;
//        	double [][] sizes = {{16, 16, 60, fill},{pref, pref}};
        	double [][] sizes = {{10, 10, 40, fill},{pref}};
        	setLayout (new TableLayout (sizes));

            // Create components
        	tableNumLabel = new JLabel ();
        	playersNamesLabel = new JLabel();
        	
//        	sizes = new double [][]{{pref, pref, pref, pref, pref, pref, pref},{pref}};

        	// Add components
        	add (tableNumLabel,     "1,0,r,c");
        	add (playersNamesLabel, "3,0,l,c");
        }

        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) 
        {
        	// Set colours up
        	setColors(isSelected);

            // Set label text and square colour.
            Table table = (Table)value;
                
            // Update values of components
            if (table != null) {
		        tableNumLabel.setText (String.valueOf(table.getTableNum()));

		        refreshPlayerLabel (table);
            }

            return this;
        }

        private void setColors(boolean isSelected)
        {
            if (isSelected) {             	
                setBackground (COLOR_SELECTED_BACKGROUND); 
                setForeground (COLOR_SELECTED_FOREGROUND); 
            } else { 
            	setBackground (COLOR_UNSELECTED_BACKGROUND);
                setForeground (COLOR_UNSELECTED_FOREGROUND); 
            } 
        }
        
        /**
         * Refresh the player panel.
         */
        private void refreshPlayerLabel (Table table) {
        	String ownerUsername = table.getOwnerUsername();
        	String otherPlayerUsername = table.getOtherPlayerUsername();
        	otherPlayerUsername = (otherPlayerUsername == null || otherPlayerUsername.isEmpty()) ? NONE_STRING : otherPlayerUsername;
        	
        	PlayerList playersListTemp = new PlayerList(table.getPlayerList());
        	playersListTemp.removePlayer(ownerUsername);
        	playersListTemp.removePlayer(otherPlayerUsername);
        	
        	String viewers = playersListTemp.toString();
        	viewers = (viewers.isEmpty()) ? NONE_STRING : viewers;
        	
        	String playersNamesString = "";
        	playersNamesString += "Owner : "        + ownerUsername       + NAMES_TYPES_SEPARATOR;
        	playersNamesString += "Other Player : " + otherPlayerUsername + NAMES_TYPES_SEPARATOR;
        	playersNamesString += "Viewers : "      + viewers;
        	
        	playersNamesLabel.setText(playersNamesString);
        }
	}
}    
